package security.config;

import framework.captcha.Captcha;
import framework.config.SecurityConfig;
import framework.config.UserConfig;
import framework.crypto.GeneralCrypto;
import framework.security.AccountLoader;
import framework.security.AuthService;
import framework.security.password.PasswordService;
import framework.security.token.AuthTokenBuilder;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.cache.CacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.StringUtils;
import security.service.*;

@Configuration
public class SecurityConfiguration {

    @Bean
    @ConditionalOnMissingBean
    public PasswordService passwordService(SecurityConfig securityConfig) {
        PasswordServiceDefault ps = new PasswordServiceDefault();
        if (StringUtils.hasText(securityConfig.getPasswordMode())) {
            ps.setDefaultMode(securityConfig.getPasswordMode());
        }
        return ps;
    }

    @Bean
    @ConditionalOnMissingBean
    public CaptchaFlagAdmin captchaFlagAdmin(CacheManager cacheManager) {
        return new CaptchaFlagAdminDefault(cacheManager);
    }

    @Bean
    @ConditionalOnMissingBean
    public AuthTokenBuilder authTokenBuilder(SecurityConfig securityConfig) {
        return new AuthTokenBuilderDefault(securityConfig);
    }

    @Bean
    @ConditionalOnMissingBean
    public AuthService authService(UserConfig userConfig) {
        return new AuthServiceDefault(userConfig);
    }

    @Bean
    @ConditionalOnMissingBean
    public AuthTokenGenerator tokenGenerator(SecurityConfig securityConfig, CacheManager cacheManager) {
        return new AuthTokenGeneratorDefault(securityConfig, cacheManager);
    }

    @Bean
    @ConditionalOnMissingBean
    public AccountChecker accountChecker(AccountLoader accountLoader, PasswordService passwordService, SecurityConfig securityConfig, GeneralCrypto generalCrypto) {
        return new AccountCheckerDefault(accountLoader, passwordService, securityConfig, generalCrypto);
    }

    @Bean
    @ConditionalOnMissingBean
    public SecurityContext securityContext(AccountLoader accountLoader
            , SecurityConfig securityConfig
            , AuthTokenBuilder tokenBuilder
            , AccountChecker accountChecker
            , FunctionPermissionLoader[] functionPermissionLoaders
            , AuthTokenGenerator authTokenGenerator
            , AuthService authService
            , PasswordService passwordService) {
        return new SecurityContext(
                accountLoader,
                authService,
                passwordService,
                securityConfig,
                tokenBuilder,
                accountChecker,
                functionPermissionLoaders,
                authTokenGenerator
        );
    }

    @Bean
    @ConditionalOnMissingBean
    public LoginService loginService(
            SecurityContext securityContext,
            GeneralCrypto generalCrypto,
            CaptchaFlagAdmin captchaFlagAdmin,
            Captcha captcha) {
        return new LoginServiceDefault(generalCrypto, securityContext, captcha, captchaFlagAdmin);
    }

}
